import { FieldType } from "@/components/dynamicform/formdatastruct";
import { Card, ChartMeta, Edge, FlowchartJSON, Node, ProjectMeta, SimulationConfig } from "@/components/flowchart/models"
import axios, { AxiosError, AxiosRequestConfig } from "axios"
import { ElMessage } from "element-plus";
import { ws } from "./ws"
axios.defaults.withCredentials = true
console.log(ws)

//根据参数部分和参数名来获取参数值
function GetQueryString(name: string): string {
    const reg = new RegExp("(^|&|)" + name + "=([^&]*)(&|$)");
    const r = window.location.hash.substring(1).match(reg);
    console.log(window.location.search, reg)
    if (r != null) {
        console.log(r, decodeURI(r[2]));
        return decodeURI(r[2]);
    }
    return "";
}


axios.interceptors.request.use((config: AxiosRequestConfig) => {
    if (config == null) {
        throw Error("Request config is null")
    }
    if (config.headers == null) {
        throw Error("Request config is null")
    }
    config.headers['Authorization'] = GetQueryString('token');
    return config;
})

axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
}, function (error: AxiosError) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    if (error == null) {
        throw Error("Error occured but the error message was null.")
    }
    console.error(error)
    ElMessage.error(`Error occured: ${error.response!.data}`)
    return Promise.reject(error.response!.data);
});

const cache: { cards: Card[] } = { cards: [] }

const getCardsFromBackend = async (): Promise<Card[]> => {
    return (await axios.get("/api/cards")).data
}

const projectInfo = {}

export const getCards = async (): Promise<Card[]> => {
    if (cache.cards.length > 0) {
        return cache.cards
    } else {
        const resp = await getCardsFromBackend()
        cache.cards = resp
        console.log(resp)
        return cache.cards
    }
}

export const revalidateCardsCache = async () => {
    const resp = await getCardsFromBackend()
    cache.cards = resp
}

export const getCardByType = async (type: string): Promise<Card> => {
    const cards = await getCards()
    const card = cards.find((item: Card) => item.id === type)
    if (card == null) {
        throw `No card found with id ${type}`
    } else {
        return card
    }
}

export const getChart = async (query: string, type: "file_name" | "chart_name"): Promise<FlowchartJSON> => {
    const resp = await axios.get(`/api/chart?type=${type}&query=${query}`)
    return resp.data
}

export const run = async (data: { edges: Edge[], nodes: Node[]; }): Promise<void> => {
    await axios.post("/api/run", data)
    return
}

export const getChartsMeta = async (): Promise<ChartMeta[]> => {
    const resp = await axios.get("/api/all-charts")
    return resp.data
}

export const saveChart = async (query: string, type: "file_name" | "chart_name", data: FlowchartJSON): Promise<boolean> => {
    await axios.post("/api/save", {
        query,
        type,
        data: JSON.stringify(data)
    })
    return true
}
export const renameChart = async (lastName: string, newName: string): Promise<boolean> => {
    await axios.post("/api/rename-chart", {
        lastName,
        newName
    })
    return true
}

export const newRoute = async (name: string): Promise<boolean> => {
    await axios.post("/api/new-route", {
        name
    })
    return true
}

export const newProject = async (name: string, newProjectDir: string): Promise<void> => {
    await axios.post("/api/project/new-project", {
        name,
        newProjectDir
    })
}


export const openProject = async (workdir: string): Promise<void> => {
    await axios.post("/api/project/open-project", {
        workdir
    })
}

export const getRecentProjects = async (): Promise<ProjectMeta[]> => {
    return (await axios.get("/api/project/recent-projects")).data
}

export const openFolder = async (type: 'cwd'): Promise<void> => {
    await axios.post("/api/project/open-folder", { type })
    return
}

export const getSimulationConfig = async (): Promise<Record<string, FieldType>> => {
    const resp = await axios.get("/api/project/simulation-config")
    return resp.data
}

export const saveSimulationConfig = async (config: SimulationConfig): Promise<Record<string, FieldType>> => {
    const resp = await axios.post("/api/project/save-simulation-config", config)
    return resp.data
}




